package com.shop.dingdongshoppingapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shop.dingdongshoppingapi.config.RedisKeyConfig;
import com.shop.dingdongshoppingapi.dao.UserDao;
import com.shop.dingdongshoppingapi.dao.UserLogDao;
import com.shop.dingdongshoppingapi.dto.UserAddDto;
import com.shop.dingdongshoppingapi.dto.UserFindDto;
import com.shop.dingdongshoppingapi.dto.UserLoginDto;
import com.shop.dingdongshoppingapi.entity.User;
import com.shop.dingdongshoppingapi.entity.UserLog;
import com.shop.dingdongshoppingapi.service.intf.UserService;
import com.shop.dingdongshoppingapi.type.UserLogType;
import com.shop.dingdongshoppingapi.util.JedisUtil;
import com.shop.dingdongshoppingapi.util.StringUtil;
import com.shop.dingdongshoppingapi.vo.R;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Service
public class UserServiceImpl implements UserService {
	@Resource
	private UserDao dao;
	@Resource
	private UserLogDao logDao;

	/*
	 * 登录验证手机号是否存在*/
	@Override
	public R checkPhone(String phone) {
		//1.验证是否是手机号
		System.out.println(phone);
		System.out.println(StringUtil.isPhone(phone));
		if (StringUtil.isPhone(phone)) {
			//2.查询数据库
			if (dao.selectOne(new QueryWrapper<User>().eq("phone", phone)) != null) {
				return R.ok();
			} else {
				return R.fail("亲,请先去注册");
			}
		}
		return R.fail("请输入正确的手机号!");
	}

	/*
	 * 注册验证手机号和账号是否都存在*/
	@Override
	public R checkPhoneName(UserAddDto user) {
		if (StringUtil.isPhone(user.getPhone()) && StringUtil.isNotEmpty(user.getPassword())) {
			QueryWrapper<User> wrapper = new QueryWrapper<>();
			wrapper.eq("phone", user.getPhone());
			User user1 = dao.selectOne(wrapper);

			QueryWrapper<User> wrapper1 = new QueryWrapper<>();
			wrapper1.eq("name", user.getName());
			User user2 = dao.selectOne(wrapper1);
			if(user1 == null && user2 == null){
				return R.ok();
			}else if(user1 == null && user2 != null){
				return R.fail("亲,该用户名已注册");
			}else if(user1 != null){
				return R.fail("亲,该手机号已注册");
			}
		}
		return (R.fail("请将信息填写完整"));
	}

	/*
	 * 用户注册*/
	/*
	 * 注册功能*/
	@Override
	public R register(UserAddDto user) {
		if (checkPhoneName(user).getCode() == 200) {
			if (user.getCode().equals(JedisUtil.getString(RedisKeyConfig.SMS_CODE_ADD+user.getPhone()))) {
				dao.insert(new User(user.getPhone(), user.getName(), user.getPassword()));
				return R.ok();
			}else{
				return R.fail("验证码错误");
			}
		} else {
			return R.fail(checkPhoneName(user).getMsg());
		}
	}

	/*
	 * 通过姓名登录 ,  账号唯一登录,手机/账号*/
	@Override
	public R loginByName(UserLoginDto dto) {
		//1.判断账号是否为空
		if (StringUtil.isNotEmpty(dto.getName(), dto.getPassword())) {
			//2.查询数据库 支持手机号或用户名 登录
			QueryWrapper<User> wrapper = new QueryWrapper<>();
			wrapper.eq("phone", dto.getName());
			wrapper.or().eq("name", dto.getName());
			User user = dao.selectOne(wrapper);
			//3.验证是否存在用户
			if (user != null) {
				//4.验证密码是否匹配
				if (dto.getPassword().equals(user.getPassword())) {
					//5.校验 当前账号是否在线  唯一登录
					if (JedisUtil.checkKey(RedisKeyConfig.LOGIN_UID + user.getId())) {
						return R.fail("亲,账号已登录,请勿重复登录");
					} else {
						//本次 可以登录
						//登录成功 令牌：成功标记 Token 可以很简单也可以很复杂
						//前后端分离开发中，登录成功标记采用令牌的形式，令牌:Token 登录成功的标记，一般是用户信息
						//登录分为2种：1.无状态登录(服务端不记录登录信息) 2.有状态登录(服务端记录登录信息)
						//6.令牌 存储在Redis 有效期 1.用什么数据类型 2.存储什么数据 3.有没有有效期
						//记录 令牌和对应的用户信息
						JedisUtil.addString(RedisKeyConfig.LOGIN_UID + user.getId(), JSON.toJSONString(user), RedisKeyConfig.LOGIN_UID_TIME);
						//7.日志记录
						logDao.insert(new UserLog(user.getId(), UserLogType.登录.getValue(), "用户登录", "华为", "郑州"));
						return R.ok(user.getId());
					}
				}else{
					return R.fail("密码不匹配");
				}
			}else{
				return R.fail("亲,请您先注册");
			}
		}
		return R.fail("请输入正确的账户和密码");
	}

	/*
	 * 通过手机验证码登录*/
	@Override
	public R loginByPhone(UserLoginDto dto) {
		if (dto != null) {
			//1.判断输入账户是否为空
			if (StringUtil.isNotEmpty(dto.getName(), dto.getPassword())) {
				//2.查询数据库 支持手机号或用户名 登录
				QueryWrapper<User> wrapper = new QueryWrapper<>();
				wrapper.eq("phone", dto.getName());
				wrapper.or().eq("name", dto.getName());
				User user = dao.selectOne(wrapper);
				//3.验证是否存在用户
				if (user != null) {
					//4.验证 验证码
					System.out.println(dto.getPassword());
					System.out.println(JedisUtil.getString(RedisKeyConfig.SMS_CODE_LOGIN + user.getId()));
					if (dto.getPassword().equals(JedisUtil.getString(RedisKeyConfig.SMS_CODE_LOGIN + user.getId()))) {
						//5.判断当前是否有用户登录
						if (JedisUtil.checkKey(RedisKeyConfig.LOGIN_UID + user.getId())) {
							return R.fail("当前账户已登录,请稍后再试!");
						} else {
							//6.令牌 存储在Redis 有效期 1.用什么数据类型 2.存储什么数据 3.有没有有效期
							//记录 令牌和对应的用户信息
							JedisUtil.addString(RedisKeyConfig.LOGIN_UID + user.getId(), JSON.toJSONString(user), RedisKeyConfig.LOGIN_UID_TIME);
							logDao.insert(new UserLog(user.getId(), UserLogType.登录.getValue(), "用户登录", "华为", "郑州"));
							//7.返回信息和令牌
							return R.ok(user.getId());
						}
					} else {
						return R.fail("验证码验证错误");
					}
				}else{
					return R.fail("亲,您还没有注册呢");
				}
			}
		}
		return R.fail("请输入正确用户");
	}

	/*
	 * 忘记密码*/
	@Override
	@Transactional
	public R findPass(UserFindDto dto) {
		if (dto != null) {
			if (StringUtil.isNotEmpty(dto.getPassword(), dto.getCode(), dto.getPhone())) {
				//2查询数据库 获取当前用户
				QueryWrapper<User> queryWrapper = new QueryWrapper<>();
				queryWrapper.eq("phone", dto.getPhone());
				User user = dao.selectOne(queryWrapper);
				//3校验用户是否存在
				if (user != null) {
					//4.校验验证码
					if (dto.getCode().equals(JedisUtil.getString(RedisKeyConfig.SMS_CODE_FIND + dto.getPhone()))) {
						//5.修改密码
						if (dao.updatePass(dto.getPhone(), dto.getPassword()) > 0) {
							//6.修改日志
							logDao.insert(new UserLog(user.getId(), UserLogType.密码找回.getValue(), "密码找回", "华为", "郑州"));
							//7.登陆者下线
							if (JedisUtil.checkKey(RedisKeyConfig.LOGIN_UID + user.getId())) {
								JedisUtil.delKeys(RedisKeyConfig.LOGIN_UID + user.getId());
							}
							return R.ok("亲,密码修改成功");
						}
					}
				}
			}
		}
		return R.fail("信息请填写完整");
	}

	@Override
	public R loginOut(int token) {
		if (token > 0) {
			if (JedisUtil.checkKey(RedisKeyConfig.LOGIN_UID + token)) {
				logDao.insert(new UserLog(token, UserLogType.退出.getValue(), "退出登录", "小米", "郑州"));
				JedisUtil.delKeys(RedisKeyConfig.LOGIN_UID + token);
				return R.ok();
			} else {
				return R.fail("已退出");
			}
		}
		return R.fail();
	}

	//查询登录用户
	@Override
	public R loginMyUser(Integer id) {
		if (id > 0 ){
			//2.查询数据库 支持手机号或用户名 登录
			QueryWrapper<User> wrapper = new QueryWrapper<>();
			wrapper.eq("id",id);
			User user = dao.selectOne(wrapper);
			System.out.println(user.toString());
			//3.验证是否存在用户
			if (user != null) {
				return R.ok(user);
			}
		}
		return R.fail();
	}
}
